package com.linxi.rpccompensation.util;

import cn.hutool.crypto.SecureUtil;
import com.linxi.rpccompensation.entity.ResultData;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

/**
 * RPC请求工具类
 *
 * @author admin
 */
@Component
public class HttpUtil {

	private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);
	private static final int TIME_OUT = 5 * 60 * 1000;
	@Value("${rpc.url}")
	public String url;

	/**
	 * post请求
	 *
	 * @param url
	 * @param param
	 * @return
	 * @throws IOException
	 */
	public static String post(String url, String param) throws Exception {
		logger.info("请求地址：" + url);
		logger.info("开始请求：url:" + url + "\r\nparam:" + param);
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(TIME_OUT).setConnectTimeout(TIME_OUT).build();
		httpPost.setConfig(requestConfig);
		String content = "";
		if (StringUtils.isNotBlank(param)) {
			httpPost.setEntity(new StringEntity(param, ContentType.APPLICATION_JSON));
		}
		CloseableHttpResponse response = null;
		try {
			response = httpclient.execute(httpPost);
			logger.info(String.valueOf(response));
			if (response.getStatusLine().getStatusCode() == ResponseCode.TRUE.code) {
				content = EntityUtils.toString(response.getEntity(), "UTF-8");
			}
		} finally {
			logger.info("请求结束：content:" + content);
			if (response != null) {
				response.close();
			}
		}
		return content;
	}

	/**
	 * md5加密，用于服务通信鉴权
	 *
	 * @return
	 */
	public static String md5Encrypt(String str) {
		return SecureUtil.md5(str);
	}

	public static boolean doSure(String context) {
		if (StringUtils.isNotBlank(context) && ResponseSuccess.TRUE.code.equals(context)) {
			return true;
		} else {
			return false;
		}
	}

	public String returnApiUrl(String api) {
		return this.url + api;
	}

	/**
	 * 通用执行推送 集合对象
	 *
	 * @param api   只传api接口
	 * @param param
	 * @return
	 */
	public boolean doPush(String api, Object param) throws Exception {
		String jsonData = JsonUtils.toJSONString(param);
		// 参数加密封装扩展，保留功能，未实现
		// Map<String, String> map = commonParam(api, jsonData);
		// String jsonObject = JsonUtils.toJSONString(jsonData);
		return doPushByJson(returnApiUrl(api), jsonData);
	}

	/**
	 * 通用执行推送 集合对象
	 *
	 * @param api
	 * @param param
	 * @return
	 */
	public boolean doPush(String api, List<?> param) throws Exception {
		String jsonData = JsonUtils.toJSONString(param);
		return doPushByJson(returnApiUrl(api), jsonData);
	}

	/**
	 * 定时器用于推送
	 *
	 * @param api
	 * @param jsonObject
	 * @return
	 */
	public boolean doPushByJson(String api, String jsonObject) throws Exception {
		String id = "";
		String post = post(api, jsonObject);
		ResultData result = null;
		try {
			result = JsonUtils.toBean(post, ResultData.class);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		logger.info("Result:" + result);
		if (result == null) {
			return false;
		}
		return doSure(result.getResult());
	}

	/**
	 * 响应码
	 */
	enum ResponseSuccess {

		TRUE("true", "成功"),
		FALSE("false", "失败");

		private String code;
		private String name;

		ResponseSuccess(String code, String name) {
			this.code = code;
			this.name = name;
		}
	}

	/**
	 * 响应码
	 */
	enum ResponseCode {

		TRUE(200, "成功"),
		FALSE(500, "失败");

		private int code;
		private String name;

		ResponseCode(int code, String name) {
			this.code = code;
			this.name = name;
		}
	}
}
